package com.lenovo.lcdm.team.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.lenovo.lcdm.common.enums.CommonMsgEnum;
import com.lenovo.lcdm.common.exception.BusinessException;
import com.lenovo.lcdm.common.exception.ServiceException;
import com.lenovo.lcdm.team.common.util.ValidateUtil;
import com.lenovo.lcdm.team.entity.TeamGroupRole;
import com.lenovo.lcdm.team.entity.TeamRole;
import com.lenovo.lcdm.team.mapper.TeamRoleMapper;
import com.lenovo.lcdm.team.service.ITeamGroupRoleService;
import com.lenovo.lcdm.team.service.ITeamRoleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Role Service
 * @author xujing30
 * @since 2023-12-22
 */
@Service
public class TeamRoleServiceImpl extends ServiceImpl<TeamRoleMapper, TeamRole> implements ITeamRoleService {

    @Autowired
    private ITeamGroupRoleService groupRoleService;

    @Override
    public void deleteRole(Long roleId) {
        // 删除角色组关系
        LambdaQueryWrapper<TeamGroupRole> qw = new LambdaQueryWrapper<>();
        qw.eq(TeamGroupRole::getRoleId, roleId);
        groupRoleService.remove(qw);
        // 删除角色权限配置
        baseMapper.deleteAccessPolicyByRoleId(Lists.newArrayList(roleId));
        // 删除角色
        this.removeById(roleId);
    }

    @Override
    public void saveRole(TeamRole role) throws Exception {

        validateRole(role);

        TeamRole oldRole = null;
        if(role.getId() == null){
            oldRole = new TeamRole();
            role.setCreateTime(LocalDateTime.now());
        }else{
            oldRole = this.getById(role.getId());
            if(oldRole == null){
                throw new ServiceException("Role does not exist in system!\n" ,CommonMsgEnum.FAIL.getCode());
            }
        }
        BeanUtils.copyProperties(role, oldRole);
        oldRole.setModifyTime(LocalDateTime.now());
        this.saveOrUpdate(oldRole);
    }

    @Override
    public List<TeamRole> getByGroupIds(List<Long> groupIds) {
        List<TeamRole> list = new ArrayList<>();
        LambdaQueryWrapper<TeamGroupRole> groupRoleQw = new LambdaQueryWrapper<>();
        groupRoleQw.in(TeamGroupRole::getGroupId, groupIds);
        List<TeamGroupRole> groupRoles = groupRoleService.list(groupRoleQw);
        List<Long> roleIds = groupRoles.stream().map(TeamGroupRole::getRoleId).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(roleIds)) {
            list = this.listByIds(roleIds);
        }
        return list;
    }

    private void validateRole(TeamRole role) throws Exception{
        StringBuffer buffer = new StringBuffer();
        String roleName = role.getRoleName();
        String roleDesc = role.getRoleDesc();

        if (StringUtils.isEmpty(roleName)) {
            buffer.append("RoleName cannot be empty!\n");
        }
        if (StringUtils.isNotEmpty(roleName) && !ValidateUtil.checkName(roleName)) {
            buffer.append("RoleName must be the combination of Latin alphabet, digit or underscore (i.e. _).\n");
        }
        List<TeamRole> existRoles = this.getByName(roleName);
        if(!CollectionUtils.isEmpty(existRoles) && (role.getId() == null || existRoles.size() > 1 || existRoles.get(0).getId().intValue() != role.getId().intValue())){
            buffer.append("RoleName exists in system!\n");
        }

        if (StringUtils.isNotEmpty(roleDesc) && roleDesc.length() > 200) {
            buffer.append("RoleDesc can't longer than 200!\n");
        }
        if(buffer.length() > 0){
            throw new BusinessException(buffer.toString(), CommonMsgEnum.FAIL.getCode());
        }
    }



    /**
     * 根据角色名称查询
     * @param roleName
     * @return
     */
    private List<TeamRole> getByName(String roleName){
        LambdaQueryWrapper<TeamRole> qw = new LambdaQueryWrapper<>();
        qw.eq(TeamRole::getRoleName, roleName);
        return this.list(qw);
    }


}
